import React from 'react'
import 'sq-ui/lib/common.css';
import style from './style'
import '../containers/app/common'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as authAction from '../actions/auth.action'
import { fileUpload } from '../actions/file.action'
import { Link, Toast, IconFont } from '../ui-components'
import { Link as NewLink } from 'sq-ui';
import cx from 'classnames'
import { findDOMNode } from 'react-dom'
import util from '../util'
import rule from '../libs/rule'
import logo from '../images/logo.svg'

export default
@connect(null, dispatch => ({actions: bindActionCreators({ ...authAction, fileUpload }, dispatch)}))
class App extends React.Component {

  state = {
    el: null,
    invalid: true
  }

	static contextTypes = {
		router: React.PropTypes.object
	}

  constructor(props) {
    super(props)
    this.tip = this.tip()
  }

  componentWillReceiveProps(props) {
    if (props.location.pathname != this.props.location.pathname) {
      this.tip.clear()
    }
  }

  componentDidMount() {

    if ((window.global_params || {}).code === '4000106') {
      this.context.router.replace('/invalid');
    } else {
      this.setState({ invalid: false })
    }

    this.refs.content.onscroll = () => {
      util.bus.emit('page:scroll', this.refs.content.scrollTop)
    }

    window.onresize = () => {
      util.bus.emit('page:resize')
    }
  }

  validate(names, ctx) {
    return names.some(name => {

      let { value, el } = ctx

      if (!el) {
        value = ctx.state[name]
        el = ctx.refs[name]
      }

      const ret = rule[name].regex.test(value)
      if (!ret) {
        if (!value.trim()) this.tip(el, '不能为空', name)
        else {
          this.tip(el, rule[name].msg, name)
        }
      } else {
        this.tip.destroy(name)
      }
      return !ret
    })
  }

  tip() {
    let tips = {}
    const fn = (el, msg, name) => {
      let scrollTop = 0
      let tip
      const isExist = tips[name]
      if (isExist) tip = tips[name].el
      else {
        tip = document.createElement('div')
      }
      const onScroll = scrollTop => {
        scrollTop = scrollTop
        update()
      }
      const onResize = () => update()
      if (!isExist) {
        tips[name] = {
          el: tip,
          listeners: {
            onScroll,
            onResize
          }
        }
      }
      tip.className = style.tip
      if (!isExist) {
        document.body.appendChild(tip)
      }

      update()

      function update() {
        const { left, top, width, height } = el.getBoundingClientRect()
        let dy, dx=5
        tip.textContent = msg
        tip.style.top = `${top}px`
        tip.style.left = `${left + width + dx}px`

        const { height: h } = tip.getBoundingClientRect()
        dy = (height - h)/2
        tip.style.top = `${top + dy - scrollTop}px`
        tip.style.opacity = 1
      }

      util.bus.on('page:scroll', onScroll)
      util.bus.on('page:resize', onResize)
    }
    fn.destroy = name => {
      if (tips[name]) {
        const { el, listeners } = tips[name]
        el.parentNode.removeChild(el)
        util.bus.off('page:scroll', listeners.onScroll)
        util.bus.off('page:resize', listeners.onResize)
        delete tips[name]
      }
    }
    fn.clear = () => {
      util.bus.off('page:scroll')
      util.bus.off('page:resize')
      for(var i in tips) {
        tips[i].el.parentNode.removeChild(tips[i].el)
      }
      tips = {}
    }
    return fn
  }

	render() {
    const { pathname } = this.props.location
		return (
			<div className={style.root}>
        <NewLink to="/login" className={style.logo}>
          <img src={logo} />
        </NewLink>
        <div ref="content" className={cx(style.content, {
          [style[pathname.slice(1)]]: true
        })}>
					{
						React.Children.map(this.props.children, child => React.cloneElement(child, {
							...this.props.actions,
              validate: this.validate.bind(this),
              check: res => /^20\d+$/.test(res.code),
              invalid: this.state.invalid
						}))
					}
				</div>
				<Toast className={style.toast}/>
			</div>
		)
	}
}
